/**
 * 
 */
package dms.repository.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;

import dms.model.Building;
import dms.model.Campus;
import dms.model.util.FindUtil;
import dms.model.util.PageIterator;
import dms.repository.BuildingRepository;
import dms.util.HibernateUtil;

/**
 * @author 李健
 *
 */
public class BuildingRepositoryHibernate implements BuildingRepository {

	@Override
	public Building createBuilding(Building building) {
		Session session = null;
		Transaction tx = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.save(building);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return building;
	}

	@Override
	public void deleteBuildingById(Long id) {
		Session session = null;
		Transaction tx = null;
		Building building = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			building = (Building) session.load(Building.class, id);
			session.delete(building);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	@Override
	public PageIterator<Building> findAll(int start, int count) {
		Session session = null;
		Transaction tx = null;
		Building building = null;
		PageIterator<Building> pageIter = null;
		Long allCount = null;
		List<Building> list = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			String countQuery = "select count(*) from Building b";
			String findQuery = "select b from Building b";
			
			allCount = FindUtil.calculateAllCount(session, countQuery, null);
			list = FindUtil.getEntitiesByPage(session, findQuery, null, start, count);
			
			pageIter = new PageIterator<Building>(list, allCount, start, count);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return pageIter;
	}

	@Override
	public PageIterator<Building> findByCampus(int start, int count,
			Campus campus) {
		Session session = null;
		Transaction tx = null;
		Building building = null;
		PageIterator<Building> pageIter = null;
		Long allCount = null;
		List<Building> list = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			String countQuery = "select count(*) from Building b where b.campus = ?";
			String findQuery = "select b from Building b where b.campus = ?";
			Collection<Object> params = new ArrayList<Object>();
			params.add(campus);
			
			allCount = FindUtil.calculateAllCount(session, countQuery, params);
			list = FindUtil.getEntitiesByPage(session, findQuery, params, start, count);
			pageIter = new PageIterator<Building>(list, allCount, start, count);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return pageIter;
	}
	

	@Override
	public Building findById(Long id) {
		Session session = null;
		Transaction tx = null;
		Building building = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			building = (Building) session.load(Building.class, id);
			//initialize property
			Hibernate.initialize(building);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
		return building;
	}

	@Override
	public Building updateBuilding(Building building) {
		Session session = null;
		Transaction tx = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.merge(building);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return building;
	}

	@Override
	public void deleteBuildings(List<Long> ids) {
		Session session = null;
		Transaction tx = null;
		
		String deleteQuery = "delete from Building b where b.id in (:ids)";
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.createQuery(deleteQuery)
				   .setParameterList("ids", ids)
				   .executeUpdate();
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}		
		
	}
	
}
